﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;

namespace Lanscape.DMS.Business
{
    public class BinaryData
    {
        bool isNew = false;
        bool isDirty = false;
        bool isDataLoaded = false;
        bool isBinaryDataLoaded = false;

        Guid id = Guid.Empty;
        byte[] data = null;
        bool isCompressed = false;
        double length = 0;

        public BinaryData()
        {
            this.isNew = true;
            this.id = Guid.NewGuid();
            this.isDirty = true;
        }

        public BinaryData(Guid pID)
        {
            this.id = pID;
        }

        public Guid ID
        { get { return this.id; } }

        public Byte[] Data
        {
            get
            {
                if (this.isBinaryDataLoaded) { return this.data; }
                else
                {
                    loadBinaryData();
                    return data;
                }
            }

            set
            {
                this.data = value;
                this.isDirty = true;
            }
        }

        public bool IsCompressed
        {
            get
            {
                if (this.isDataLoaded) { return this.isCompressed; }
                else
                {
                    loadRest();
                    return isCompressed;
                }
            }

            set
            {
                this.isCompressed = value;
                this.isDirty = true;
            }
        }

        public double Length
        {
            get
            {
                if (this.isDataLoaded) { return this.length; }
                else
                {
                    loadRest();
                    return length;
                }
            }

            set
            {
                this.length = value;
                this.isDirty = true;
            }
        }

        private void loadRest()
        {
            if (!isNew)
            {
                string loadScript = "SELECT ID, ISCOMPRESSED, LENGTH FROM BINARYDATA WHERE ID = @ID";

                using (var sqlCon = new SqlConnection(Utility.GetConnectionString()))
                {
                    using (var sqlCmd = new SqlCommand(loadScript))
                    {
                        sqlCmd.Connection = sqlCon;
                        sqlCmd.Parameters.Add(new SqlParameter("@ID", System.Data.SqlDbType.UniqueIdentifier));
                        sqlCmd.Parameters[0].Value = this.id;

                        var sDr = sqlCmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
                        if (sDr != null && sDr.HasRows)
                        {
                            sDr.Read();
                            this.isCompressed = sDr.GetBoolean(1);
                            this.length = sDr.GetDouble(2);
                        }

                        this.isDataLoaded = true;
                    }
                }
            }
        }

        private void loadBinaryData()
        {
            if (!isNew)
            {
                string loadScript = "SELECT DATA FROM BINARYDATA WHERE ID = @ID";

                using (var sqlCon = new SqlConnection(Utility.GetConnectionString()))
                {
                    using (var sqlCmd = new SqlCommand(loadScript))
                    {
                        sqlCmd.Connection = sqlCon;
                        sqlCmd.Parameters.Add(new SqlParameter("@ID", System.Data.SqlDbType.UniqueIdentifier));
                        sqlCmd.Parameters[0].Value = this.id;

                        var sDr = sqlCmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection);
                        if (sDr != null && sDr.HasRows)
                        {
                            sDr.Read();
                            this.data = (byte[])sDr.GetValue(0);
                        }

                        this.isBinaryDataLoaded = true;
                    }
                }
            }
        }

        public void Save()
        {
            if (isDirty)
            {
                if (isNew)
                {
                    string insertScript = "INSERT INTO BINARYDATA (ID, DATA, ISCOMPRESSED, LENGTH) VALUES(@ID, @DATA, @ISCOMPRESSED, @LENGTH)";

                    using (var sqlCon = new SqlConnection(Utility.GetConnectionString()))
                    {
                        using (var sqlCom = new SqlCommand(insertScript))
                        {
                            sqlCom.Connection = sqlCon;

                            sqlCom.Parameters.Add(new SqlParameter("@ID", System.Data.SqlDbType.UniqueIdentifier));
                            sqlCom.Parameters["@ID"].Value = this.id;

                            sqlCom.Parameters.Add(new SqlParameter("@DATA", System.Data.SqlDbType.VarBinary));
                            sqlCom.Parameters["@DATA"].Value = this.data;

                            sqlCom.Parameters.Add(new SqlParameter("@ISCOMPRESSED", System.Data.SqlDbType.Bit));
                            sqlCom.Parameters["@ISCOMPRESSED"].Value = this.isCompressed;

                            sqlCom.Parameters.Add(new SqlParameter("@LENGTH", System.Data.SqlDbType.BigInt));
                            sqlCom.Parameters["@LENGTH"].Value = this.length;

                            sqlCon.Open();
                            sqlCom.ExecuteNonQuery();
                        }
                    }
                }
                else
                {
                    using (var sqlCon = new SqlConnection(Utility.GetConnectionString()))
                    {
                        using (var sqlCom = new SqlCommand())
                        {
                            sqlCom.Connection = sqlCon;
                            
                            
                            if (this.isBinaryDataLoaded)
                            {
                                string updateScript = "UPDATE BINARYDATA SET DATA = @DATA, ISCOMPRESSED = @ISCOMPRESSED, LENGTH = @LENGTH WHERE ID = @ID";
                                sqlCom.CommandText = updateScript;

                                sqlCom.Parameters.Add(new SqlParameter("@ID", System.Data.SqlDbType.UniqueIdentifier));
                                sqlCom.Parameters["@ID"].Value = this.id;

                                sqlCom.Parameters.Add(new SqlParameter("@DATA", System.Data.SqlDbType.VarBinary));
                                sqlCom.Parameters["@DATA"].Value = this.data;

                                sqlCom.Parameters.Add(new SqlParameter("@ISCOMPRESSED", System.Data.SqlDbType.Bit));
                                sqlCom.Parameters["@ISCOMPRESSED"].Value = this.isCompressed;

                                sqlCom.Parameters.Add(new SqlParameter("@LENGTH", System.Data.SqlDbType.BigInt));
                                sqlCom.Parameters["@LENGTH"].Value = this.length;
                            }
                            else
                            {
                                string updateScript = "UPDATE BINARYDATA SET ISCOMPRESSED = @ISCOMPRESSED, LENGTH = @LENGTH WHERE ID = @ID";

                                sqlCom.CommandText = updateScript;
                                sqlCom.CommandType = System.Data.CommandType.Text;

                                sqlCom.Parameters.Add(new SqlParameter("@ID", System.Data.SqlDbType.UniqueIdentifier));
                                sqlCom.Parameters["@ID"].Value = this.id;

                                sqlCom.Parameters.Add(new SqlParameter("@ISCOMPRESSED", System.Data.SqlDbType.Bit));
                                sqlCom.Parameters["@ISCOMPRESSED"].Value = this.isCompressed;

                                sqlCom.Parameters.Add(new SqlParameter("@LENGTH", System.Data.SqlDbType.BigInt));
                                sqlCom.Parameters["@LENGTH"].Value = this.length;
                            }
                            
                            sqlCon.Open();
                            sqlCom.ExecuteNonQuery();
                        }
                    }
                }
            }
        }
    }
}
